package ucla.axelia.controlador.servicios;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Order;

import com.obelisco.modelo.data.DataGenerica;
import com.obelisco.vista.inicio.Aplicacion;

import ucla.axelia.controlador.interfaces.IServicioAdministracionActividadPlanificada;
import ucla.axelia.modelo.beans.RespuestaCerrada;
import ucla.axelia.modelo.dao.ServicioActividadPlanificadaDAO;
import ucla.axelia.modelo.dao.ServicioProgramaDAO;
import ucla.axelia.modelo.dao.ServicioTipoActividadDAO;
import ucla.axelia.modelo.dao.ServicioUsuarioProgramaDAO;
import ucla.axelia.modelo.data.Actividad;
import ucla.axelia.modelo.data.ActividadPlanificada;

public class ServicioAdministracionActividadPlanificada implements IServicioAdministracionActividadPlanificada {

	private ServicioActividadPlanificadaDAO servicioActividadPlanificadaDAO;
	private ServicioProgramaDAO servicioProgramaDAO;
	private ServicioUsuarioProgramaDAO servicioUsuarioProgramaDAO;
	private ServicioTipoActividadDAO servicioTipoActividadDAO;

	
    public List buscarProgramasPorUsuarioActual() {
		String login = Aplicacion.getApp().getContexto().getUsuarioActual().getLogin();
		List result = this.servicioUsuarioProgramaDAO.buscarProgramasPorUsuario(login);
		return result;
	}
    
	public List buscarTipoActividades() {
		List orden = new ArrayList();
		orden.add(Order.asc("nombreTipoActividad"));
		return servicioTipoActividadDAO.buscarTodos(DataGenerica.DATA_ACTIVO, orden);
	}
	
	public List buscarProgramas() {
		List orden = new ArrayList();
		orden.add(Order.asc("nombrePrograma"));
		return servicioProgramaDAO.buscarTodos(DataGenerica.DATA_ACTIVO, orden);	
	}
	
	public List buscarActividadesPlanificadasPorCriterios(Map criterios) {
		List actividadesPlanificada = new ArrayList();
		List programasPorUsuario = this.buscarProgramasPorUsuarioActual();
		if ((programasPorUsuario != null) &&
			(programasPorUsuario.size() > 0)) {
			Session session = this.servicioActividadPlanificadaDAO.getSessionFactory().getCurrentSession();
			Date fechaAux=null;
			String modo = "";
			
			String sentencia = "Select actividadPlanificada " +
							   "from ActividadPlanificada actividadPlanificada "+
							   "where actividadPlanificada.estado = :estado "+
							   "and actividadPlanificada.actividad.programa in (:programas) ";
			for (int i=0; i<criterios.size(); i++){
				String llave = (String)criterios.keySet().toArray()[i];
				Object valor = (criterios.get(criterios.keySet().toArray()[i]));
				if (llave.equals("actividad.nombreActividad")) {
					sentencia += "and upper(actividadPlanificada."+llave+") like '%"+valor.toString().toUpperCase()+"%' ";
				}
				else if (llave.equals("fechaReferencial")) {
					fechaAux = (Date)valor;
					sentencia += "and actividadPlanificada.fechaInicioActividadPlanificada <= :fechaAux "+
								 "and actividadPlanificada.fechaFinActividadPlanificada >= :fechaAux ";
				}
				else if (llave.equals("modo")) {
					modo = valor.toString().trim();
					if ((valor.equals("Planificacion")) ||
						(valor.equals("Asignacion")) ||
						(valor.equals("Ejecucion")) ||
						(valor.equals("Suspension"))) {
						sentencia += "and actividadPlanificada.actividadEjecutada is null " ;
						sentencia += "and actividadPlanificada.suspendida = '"+RespuestaCerrada.NO+"' ";
					}
					else if (valor.equals("Reanudacion")) {
						sentencia += "and actividadPlanificada.actividadEjecutada is null " ;
						sentencia += "and actividadPlanificada.suspendida = '"+RespuestaCerrada.SI+"' ";
					}
				}
				else {
					sentencia += "and actividadPlanificada."+llave+" = '"+valor+"' ";
				}
			}
			sentencia+="order by upper(actividadPlanificada.actividad.nombreActividad)";
			Query qry = session.createQuery(sentencia);
			qry.setString("estado", DataGenerica.DATA_ACTIVO);
			qry.setParameterList("programas", programasPorUsuario);
			if (fechaAux != null) {
				qry.setDate("fechaAux", fechaAux);
			}		
			actividadesPlanificada = qry.list();
			
			for (Iterator iter = actividadesPlanificada.iterator(); iter.hasNext();) {
				ActividadPlanificada actividadPlanificada = (ActividadPlanificada) iter.next();
				actividadPlanificada.getHorarioActividadPlanificadas().size();
				if (modo.equals("Planificacion")) {					
					actividadPlanificada.getCantidadvoluntarioProgramas().size();
				}
				else if (modo.equals("Asignacion")) {
					actividadPlanificada.getVoluntarioAsignados().size();					
					Actividad actividad = actividadPlanificada.getActividad();
					actividad.getPerfilActividads().size();
					actividad.getActividadEnfermedads().size();
					actividad.getActividadAlergias().size();
				}
				else if (modo.equals("Ejecucion")) {
					actividadPlanificada.getVoluntarioAsignados().size();					
				}
				else if (modo.equals("Reanudacion")) {
					actividadPlanificada.getActividadSuspendidas().size();
				}
			}
		}
		return actividadesPlanificada;
	}
	
	public List buscarActividadesPlanificadas() {
		List actividadesPlanificada = new ArrayList();
		List programasPorUsuario = this.buscarProgramasPorUsuarioActual();
		if ((programasPorUsuario != null) &&
			(programasPorUsuario.size() > 0)) {
			Session session = this.servicioActividadPlanificadaDAO.getSessionFactory().getCurrentSession();			
			String sentencia = "Select actividadPlanificada " +
							   "from ActividadPlanificada actividadPlanificada "+
							   "where actividadPlanificada.estado = :estado "+
							   "and actividadPlanificada.actividad.programa in (:programas) "+
							   "and actividadPlanificada.actividadEjecutada is null "+
							   "and actividadPlanificada.suspendida = '"+RespuestaCerrada.NO+"' "+
							   "order by upper(actividadPlanificada.actividad.nombreActividad)";
			Query qry = session.createQuery(sentencia);
			qry.setString("estado", DataGenerica.DATA_ACTIVO);
			qry.setParameterList("programas", programasPorUsuario);
			actividadesPlanificada = qry.list();
			
			for (Iterator iter = actividadesPlanificada.iterator(); iter.hasNext();) {
				ActividadPlanificada actividadPlanificada = (ActividadPlanificada) iter.next();				
				actividadPlanificada.getCantidadvoluntarioProgramas().size();
				actividadPlanificada.getHorarioActividadPlanificadas().size();
			}
		}
		return actividadesPlanificada;
	}
	
	private void borrarSetDeActividadPlanificada(String hql, ActividadPlanificada actividadPlanificada) {
		Session session = this.servicioActividadPlanificadaDAO.getSessionFactory().getCurrentSession();
		Query query = session.createQuery(hql);
		query.setEntity("actividadPlanificada", actividadPlanificada);
		int rowCount = query.executeUpdate();
	}
	
	public void guardarActividadPlanificada(ActividadPlanificada actividadPlanificada) {
		if (actividadPlanificada.getIdActividadPlanificada() != null) {
			// Borramos los horarios de la actividad planificada
			this.borrarSetDeActividadPlanificada("DELETE FROM HorarioActividadPlanificada hap where hap.actividadPlanificada = :actividadPlanificada", actividadPlanificada);
			// Borramos la cantidad de voluntarios por programa de la actvidad planificada
			this.borrarSetDeActividadPlanificada("DELETE FROM CantidadvoluntarioPrograma cvp where cvp.actividadPlanificada = :actividadPlanificada", actividadPlanificada);
		}
		// Guardamos el voluntario
		this.servicioActividadPlanificadaDAO.guardar(actividadPlanificada);
	}

	public void eliminarActividadPlanificada(ActividadPlanificada actividadPlanificada) {
		servicioActividadPlanificadaDAO.eliminarFisicamente(actividadPlanificada);
	}


	// Getter y Setter
	public ServicioActividadPlanificadaDAO getServicioActividadPlanificadaDAO() {
		return servicioActividadPlanificadaDAO;
	}

	public void setServicioActividadPlanificadaDAO(ServicioActividadPlanificadaDAO servicioActividadPlanificadaDAO) {
		this.servicioActividadPlanificadaDAO = servicioActividadPlanificadaDAO;
	}
	
	public ServicioProgramaDAO getServicioProgramaDAO() {
		return servicioProgramaDAO;
	}
	
	public void setServicioProgramaDAO(ServicioProgramaDAO servicioProgramaDAO) {
		this.servicioProgramaDAO = servicioProgramaDAO;
	}
	
	public ServicioUsuarioProgramaDAO getServicioUsuarioProgramaDAO() {
		return servicioUsuarioProgramaDAO;
	}
	
	public void setServicioUsuarioProgramaDAO(
			ServicioUsuarioProgramaDAO servicioUsuarioProgramaDAO) {
		this.servicioUsuarioProgramaDAO = servicioUsuarioProgramaDAO;
	}
	
	public ServicioTipoActividadDAO getServicioTipoActividadDAO() {
		return servicioTipoActividadDAO;
	}
	
	public void setServicioTipoActividadDAO(
			ServicioTipoActividadDAO servicioTipoActividadDAO) {
		this.servicioTipoActividadDAO = servicioTipoActividadDAO;
	}

}